<?php
/**
 * @Notes:【】
 * @User: zwc
 * @Date: 2022-05-04 21:30
 */

namespace App\Service\Task;

use App\Constants\SignTask;
use App\Dao\Task\TaskDao;
use App\Dao\Task\TaskReceiveDao;
use App\Dao\Task\TaskReceiveDetailDao;
use App\Dao\Task\TaskStepsDao;
use App\Dao\Task\TaskStepsRulesDao;
use App\Dao\Task\TaskTypesDao;
use App\Dao\User\UserDao;
use App\Dao\User\UserMoneyDao;
use App\Model\Task\TaskReceive;
use App\Model\Task\TaskSteps;
use App\Model\Task\TaskStepsRules;
use App\Service\BaseService;
use App\Service\Sign\SignTaskService;
use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Utils\Collection;

class TaskReceiveService extends BaseService
{
    /**
     * @Inject()
     * @var TaskDao
     */
    protected $taskDao;

    /**
     * @Inject()
     * @var TaskStepsDao
     */
    protected $taskStepsDao;

    /**
     * @Inject()
     * @var TaskStepsRulesDao
     */
    protected $taskStepsRuleDao;
    /**
     * @Inject()
     * @var TaskTypesDao
     */
    protected $taskTypesDao;

    /**
     * @Inject()
     * @var TaskReceiveDao
     */
    public $taskRevicesDao;

    /**
     * @Inject()
     * @var TaskReceiveDetailDao
     */
    protected $taskRevicesdetailDao;

    public function add(Collection $data)
    {
        Db::beginTransaction();
        try {
            $task = $this->taskDao->create($data->toArray());
            $taskSteps = collect($data->get('steps'));
            $taskSteps->every(function ($step) use ($task) {
                $taskSteps = $task->TaskSteps()->save(new TaskSteps([
                    'title' => $step['title'],
                ]));
                $rules = collect($step['rules']);
                $rules->transform(function ($rule) {
                    if (empty($rule['value'])) {
                        _Exception("请填写{$rule['title']}");
                    }
                    return new TaskStepsRules($rule);
                });
                $taskSteps->TaskStepsRules()->saveMany($rules);
                return true;
            });
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
            _Error($e->getMessage());
        }
        return $task;
    }

    public function lists($validator)
    {
        $data = $this->taskRevicesDao
            ->DaoWhereStatus($validator->get('status'))
            ->DaoWhere($validator->toArray())
            ->with(['Task' => function ($query) {
                $query->with(['image', 'TaskTypes']);
            }, 'user'])
            ->orderByDesc('id')
            ->getList();
        _SUCCESS($data);
    }

    public function getTypes()
    {
        $data = $this->taskTypesDao->getList();
        _SUCCESS($data);
    }

    public function edit($task_id, \App\Tool\Collect|Collection $data)
    {
        Db::beginTransaction();
        try {
            $taskDao = $this->taskDao->where('id', $task_id)->firstOrError();
            $taskDao->fill($data->toArray());
            $taskDao->save();
            $this->updateSteps($task_id, $data->get('task_steps'));
            Db::commit();
        } catch (\Exception $exception) {
            Db::rollback();
            _Error($exception->getMessage());
        }
        return true;
    }

    public function updateSteps($task_id, $task_steps)
    {
        $taskSteps = _Collect($task_steps);
        $ids = $taskSteps->where('id', '>', 0)->pluck('id');
        //删除
        $this->taskStepsDao->where('task_id', $task_id)->where(function ($query) use ($ids) {
            $ids->isNotEmpty() && $query->whereNotIn('id', $ids->toArray());
        })->delete();

        $taskSteps->where('id', 0)->every(function ($step) use ($task_id) {
            $taskSteps = $this->taskStepsDao->create([
                'task_id' => $task_id,
                'title' => $step['title'],
            ]);
            $task_steps_rules = collect($step['task_steps_rules']);
            $task_steps_rules->transform(function ($rule) {
                if (empty($rule['value'])) {
                    _Exception("请填写{$rule['title']}");
                }
                return new TaskStepsRules($rule);
            });
            $taskSteps->TaskStepsRules()->saveMany($task_steps_rules);
            return true;
        });

        $taskSteps->where('id', '>', 0)->every(function ($step) use ($task_id) {
            dump($task_id);
            $taskSteps = $this->taskStepsDao->where('task_id', $task_id)->firstOrError();
            $taskSteps->fill($step);
            $taskSteps->save();
            $task_steps_rules = collect($step['task_steps_rules']);
            $task_steps_rules->every(function ($rule) use ($taskSteps) {
                $TaskStepsRules = $this->taskStepsRuleDao->where('task_steps_id', $rule['task_steps_id'])
                    ->where('id', $rule['id'])->firstOrError();
                $TaskStepsRules->fill($rule);
                $TaskStepsRules->save();
                return true;
            });
            return true;
        });
    }


    public function detail(\App\Tool\Collect $validator)
    {
        $detail = $this->taskRevicesDao
            ->DaoWhere($validator->only('task_receive_id')->toArray())
            ->with(['Task' => function ($query) {
                $query->with(['Image', 'TaskSteps' => function ($query) {
                    $query->with('TaskStepsRules');
                }]);
            }, 'User'])
            ->first();
        $TaskSteps = $detail->Task->TaskSteps;
        $TaskSteps->transform(function ($TaskStep) {
            $TaskStep->TaskStepsRules->transform(function ($TaskStepsRule) {
                $finish = App(TaskReceiveDetailDao::class)
                    ->where('task_steps_rules_id', $TaskStepsRule->id)
                    ->value('value');
                $TaskStepsRule->submit = $finish;
                return $TaskStepsRule;
            });

            return $TaskStep;
        });

        _GetLastSql();
        return $detail;
//        $data = $this->taskDao->DaoWhere($validator->toArray())
//            ->with(['Image', 'User', 'TaskSteps' => function ($query) {
//                $query->with('TaskStepsRules');
//            }])
//            ->first();
//        $data->isReceive = $this->taskRevicesDao->isReceive($validator->getUserId(false), $validator->get('task_id'));
//        _SUCCESS($data);
    }

    public function receive($userId, $taskId)
    {
        $isReceive = $this->taskRevicesDao->isReceive($userId, $taskId);
        if ($isReceive) {
            _Error('已经领取过了');
        }
        $this->taskRevicesDao->create([
            'user_id' => $userId,
            'task_id' => $taskId,
        ]);
        return true;
    }

    public function cancel(\App\Tool\Collect $params)
    {
        Db::beginTransaction();
        try {
            $taskRevices = $this->taskRevicesDao->cancel($params->get('taskReceiveid'), $params->get('user_id'));
            $this->taskDao->changeStock($taskRevices->task_id, 1, 'task_cancel');
            DB::commit();
        } catch (\Exception $e) {

            DB::rollBack();
            _Error($e->getMessage());
        }
        return true;
    }

    public function submitDetail(\App\Tool\Collect $data)
    {
//
//        $taskStepsRules = $this->taskStepsRuleDao
//            ->with(['TaskSteps' => function ($query) {
//                $query->with('Task');
//            }])
//            ->where('id', $data->get('task_steps_rules_id'))->firstOrError();

        $taskRevices = $this->taskRevicesDao->where('id', $data->get('task_receive_id'))->firstOrError();
        dump($taskRevices->status);
        if (!in_array($taskRevices->status, [0, 5])) {
            _Error('不能修改');
        }
        return $this->taskRevicesdetailDao->updateOrCreate($data->except('value')->toArray() + [
                'task_id' => $taskRevices->task_id
            ], $data->only('value')->toArray());

    }

    public function submit(\App\Tool\Collect $data)
    {

        //判断是否取消
        $isCancel = $this->taskRevicesDao->isCancel($data->get('task_receive_id'));
        $task_receive_id = $data->get('task_receive_id');

        //判断是否全部填写完成
        $taskRevices = $this->taskRevicesDao
            ->DaoWhere(['id' => $task_receive_id])
            ->with(['Task' => function ($query) {
                $query->with(['TaskSteps' => function ($query) {
                    $query->with('TaskStepsRules');
                }]);
            }])
            ->firstOrError();

        if ($taskRevices) {
            if (!in_array($taskRevices->status, [0, 5])) {
                _Error('已经提交过了');
            }
        }
        $isCancel && _Error('已取消');
        $TaskSteps = $taskRevices->Task->TaskSteps;

        $TaskSteps->every(function ($TaskStep) use ($task_receive_id) {
            $TaskStep->TaskStepsRules->every(function ($TaskStepsRule) use ($task_receive_id) {
                if (in_array($TaskStepsRule->field, ['screenshot'])) {
                    //寻找
                    if ($this->taskRevicesdetailDao
                        ->where('task_receive_id', $task_receive_id)
                        ->where('task_steps_rules_id', $TaskStepsRule->id)
                        ->doesntExist()) {
                        _Error('请提交完整数据');
                    }
                }
                return true;
            });
            return true;
        });
        $taskRevices->status = 10;
        $taskRevices->save();
        return $taskRevices;
    }

    /**
     * @Inject()
     * @var UserDao
     */
    protected $userDao;


    public function audit(mixed $task_receive_id, $params)
    {
        DB::beginTransaction();
        try {
            $taskRevice = $this->taskRevicesDao->DaoWhere(compact('task_receive_id'))->firstOrError();
            $cancel_time = time() + 12 * 3600;
            $taskRevice->fill($params->only(['status', 'reason'])->toArray() + ['cancel_time' => $cancel_time]);
            $taskRevice->save();
            $status = $params->get('status');
            $this->taskDao->where('id', $taskRevice->task_id)->increment('finish');
            if ($status == 100) {
                /** @var SignTaskService $signTaskService */
                $signTaskService = App(SignTaskService::class);

                //做任务
                $signTaskService->do($taskRevice->user_id, SignTask::TASK);
                $this->userDao->opAccount('integral', $taskRevice->user_id, $taskRevice->task_price * 10, 'task_settlement', $taskRevice->id);
            }
//            App(UserMoneyDao::class)->addTaskLog($taskRevice->task_id, $taskRevice->user_id);
            Db::commit();
        } catch (\Exception $exception) {
            DB::rollBack();
            _Error($exception->getMessage());
        }
        return true;
    }

    public function taskStatistics(int $task_id)
    {

        //待审核
        $auditing = $this->taskRevicesDao
            ->DaoWhere(['task_id' => $task_id])
            ->where('status', 10)
            ->count();

        //驳回
        $barge = $this->taskRevicesDao
            ->DaoWhere(['task_id' => $task_id])
            ->where('status', 5)
            ->count();

        //申诉
        $appeal = $this->taskRevicesDao
            ->DaoWhere(['task_id' => $task_id])
            ->where('status', 2)
            ->count();

        $success = $this->taskRevicesDao
            ->DaoWhere(['task_id' => $task_id])
            ->where('status', 100)
            ->count();

        $wait_submit = $this->taskRevicesDao->DaoWhere(['task_id' => $task_id])
            ->where('status', 0)
            ->count();


        $repairing = $this->taskRevicesDao
            ->DaoWhere(['task_id' => $task_id])
            ->where('status', 5)
            ->count();

        $delete = $this->taskRevicesDao
            ->DaoWhere(['task_id' => $task_id])
            ->withTrashed()
            ->count();

        return compact(
            'barge',
            'auditing',
            'success',
            'repairing',
            'wait_submit',
            'appeal',
            'delete'
        );

    }

    public function statistics(int $usersId)
    {
        $processing = $this->taskRevicesDao->DaoWhere(['user_id' => $usersId])
            ->where('status', 0)
            ->count();

        $auditing = $this->taskRevicesDao
            ->DaoWhere(['user_id' => $usersId])
            ->where('status', 10)
            ->count();

        $repairing = $this->taskRevicesDao
            ->DaoWhere(['user_id' => $usersId])
            ->where('status', 5)
            ->count();

        $success = $this->taskRevicesDao
            ->DaoWhere(['user_id' => $usersId])
            ->where('status', 100)
            ->count();
        $error = $this->taskRevicesDao
            ->DaoWhere(['user_id' => $usersId])
            ->where('status', -1)
            ->count();

        return compact(
            'auditing',
            'success',
            'repairing',
            'processing',
            'error'
        );

    }


    public function hot()
    {
        $data = $this->taskRevicesDao
            ->with(['Task', 'User'])
            ->where('status', 100)
            ->getList();
        $data->setAppends(['create_time_format']);
        return $data;
    }

}